from bipy import util        

class Dynamic(object):
    def __init__(self):
        super(Dynamic, self).__init__()
        self.components = []


    def add_component(self, comp):
        if comp.dynamic:
            comp.dynamic.remove_component(comp)
        for req in comp.requirements:
            if not self.has( req ):
                raise NotImplementedError, "%s requires parent Dynamic to install %s" % (comp.name, req)
        comp.dynamic = self
        setattr(self, comp.name, comp)
        for idx in range( len( self.components ) ):
            if comp.prio < self.components[ idx ].prio:
                self.components.insert(idx, comp)
                break
        #self.signal_comp_added.emit(self, comp)
        
        
    def remove_component(self, comp):
        if hasattr(self, comp.name):
            #comp.signal_comp_goingtoremove.emit(self, comp)
            delattr(self, comp.name)
            self.components.remove(comp)
            #self.signal_comp_removed.emit(self, comp)
            comp.dynamic = None
            
    def has(self, name):
        if hasattr(self, name):
            return True
        return False
            
    def on_update(self, dt):
        for comp in self.components:
            comp.update(dt)
           
class Component(object):
    requirements = []
    def __init__(self, name, prio):
        super(Component, self).__init__()
        self.name = name
        self.prio = prio
        self.dynamic = None
        
    def update(self, dt):
        pass
        
_loaded_component_classes = {} 

def get( comp_name ):
    if comp_name in _loaded_component_classes:
        return _loaded_component_classes[ comp_name ]
    full_path = '.'.join( [__name__, comp_name, 'component_class'] )
    cls = util._get_class(full_path, parentClass=Component)
    if cls:
        _loaded_component_classes[ comp_name ] = cls
        return cls
    else:
        return None